/*
 * Window.h
 *
 *  Created on: 2012-8-27
 *      Author: yangentao@gmail.com
 */

#ifndef WINDOW_H_
#define WINDOW_H_

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include <vector>
#include <algorithm>

#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
#include <boost/function.hpp>

#include "../util/util.h"
#include "../include/platform.h"
#include "WndUtil.h"

using namespace std;

using soy::Rect;

template<typename T>
struct LastValue {
	typedef T result_type;

	template<typename InputIterator>
	T operator()(InputIterator first, InputIterator last) const {
		if (first == last)
			return T();
		T val = *first++;
		while (first != last) {
			val = *first;
			++first;
		}
		return val;
	}
};

namespace ui {

class WindowMessageListener {
public:
	virtual ~WindowMessageListener();
	virtual HRESULT onMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& handled);
	virtual HRESULT operator()(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& handled);
};

class WindowClass {
public:
	WNDCLASSEX classEx;
	ATOM atom;
public:
	WindowClass();
	virtual ~WindowClass();
public:
	//use XWndProc
	void createClass(LPCTSTR className);
	void createClass(LPCTSTR className, WNDPROC wndPRoc);
	void createClass(LPCTSTR className, WNDPROC wndPRoc, UINT iconResID, UINT iconSmallResID, UINT menuResID);
	bool registerClass();
	void unregisterClass();
	bool isRegistered();
};

class WindowX: public WndUtil {
	typedef WndUtil Super;

	typedef boost::signals2::signal<void(HWND)> FinishedSignal;
	typedef boost::signals2::signal<void(HWND, CREATESTRUCT*)> CreatingSignal;
	typedef boost::signals2::signal<HRESULT(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& handled), LastValue<HRESULT> >  MessageSignal;

	typedef FinishedSignal::slot_type FinishHandler;
	typedef CreatingSignal::slot_type CreatingHandler;
	typedef MessageSignal::slot_type MessageHandler;
private:
	FinishedSignal finishedSignal;
	CreatingSignal creatingSignal;
	MessageSignal msgSignal;
public:
	WindowX();
	WindowX(HWND w);
	virtual ~WindowX();
public:
	virtual bool create(LPCTSTR clsName, LPCTSTR text, UINT style, UINT exStyle, Rect rect, HWND parent);
	virtual void subclassWindow(HWND w);
public:
	virtual void fireOnCreating(HWND w, CREATESTRUCT* createStruct);
	virtual void fireOnFinished(HWND w);
	virtual HRESULT fireOnMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& handled);
	virtual boost::signals2::connection addFinishHandler(const FinishHandler& finishHandler);
	virtual boost::signals2::connection addCreatingHandler(const CreatingHandler& creatingHandler);
	virtual boost::signals2::connection addMessageHandler(const MessageHandler& msgHandler);
	virtual boost::signals2::connection addMessageHandler(WindowMessageListener* listener);

	virtual void clearWindowListeners();

};

} /* namespace ui */
#endif /* WINDOW_H_ */
